package com.haiyou.dc.es;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class TestSearch {


    public final static String userIndexType = "user";
    public final static Double distance = 3000000D;


    private static RestClientBuilder builder;
    private static RestHighLevelClient restHighLevelClient;

    public static void start() {

        HttpHost httpHost = new HttpHost("39.108.55.247", 9200, "http");
        builder = RestClient.builder(httpHost);
        restHighLevelClient = new RestHighLevelClient(builder);
    }


    public static void main(String[] args) {
        start();

        Map<String, String> map = new HashMap<>();
        map.put("latitude", "28.185711");
        map.put("longitude", "113.032494");
        map.put("region", "芙蓉区");

        //查询索引
        SearchRequest searchRequest = new SearchRequest().indices(userIndexType).types(userIndexType);

        //距离条件
        GeoDistanceQueryBuilder geoDistanceQueryBuilder = new GeoDistanceQueryBuilder("location");
        geoDistanceQueryBuilder.point(Double.valueOf(map.get("latitude")), Double.valueOf(map.get("longitude")));
        geoDistanceQueryBuilder.distance(distance, DistanceUnit.METERS);
        geoDistanceQueryBuilder.geoDistance(GeoDistance.ARC);
        //距离排序
        GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", Double.valueOf(map.get("latitude")), Double.valueOf(map.get("longitude")));
        geoDistanceSortBuilder.unit(DistanceUnit.METERS);
        geoDistanceSortBuilder.order(SortOrder.ASC);

        //其他条件
        QueryBuilder qb1 = null;
        if (StringUtils.isNotEmpty(map.get("region"))) {
            qb1 = QueryBuilders.matchQuery("region", map.get("region"));
        } else if (StringUtils.isNotEmpty(map.get("city"))) {
            qb1 = QueryBuilders.matchQuery("city", map.get("city"));
        } else if (StringUtils.isNotEmpty(map.get("province"))) {
            qb1 = QueryBuilders.matchQuery("province", map.get("province"));
        }
        assert qb1 != null;

        MatchQueryBuilder qbRoleType = QueryBuilders.matchQuery("roleType", "3");

        QueryBuilder queryBuilder = QueryBuilders.boolQuery().must(qb1).must(qbRoleType).must(geoDistanceQueryBuilder);
        //构建条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(0).size(10);
        sourceBuilder.query(queryBuilder);
        sourceBuilder.sort(geoDistanceSortBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse response;
        try {
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            SearchHit[] searchHits = hits.getHits();
            List<UserEsEntity> list = new ArrayList<>();

            for (SearchHit hit : searchHits) {
                UserEsEntity esEntity = JSON.parseObject(hit.getSourceAsString(), UserEsEntity.class);
                if (hit.getSortValues().length != 0) {
                    BigDecimal geoDis = new BigDecimal((Double) hit.getSortValues()[0]);
                    esEntity.setDistance(geoDis.toString());
                }
                list.add(esEntity);
            }

            log.info("=======>{}", list.size());
            list.forEach(userEsEntity -> {
                log.info("--->{}", userEsEntity);
            });


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
